//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: unihan2.c 769 2007-05-14 03:39:06Z roger $
//

#include "config.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#if USE_SYSLOG
#include <syslog.h>
#endif

#include "log.h"

#define STRING_BUFFER_SIZE  32

#define ALERT_LEVELS (LOG_LEVEL_ERROR | LOG_LEVEL_CRITICAL | LOG_LEVEL_WARNING)

#ifdef DEBUG
#define LOG_LEVEL_MASK (ALERT_LEVELS | LOG_LEVEL_MESSAGE | LOG_LEVEL_INFO | LOG_LEVEL_DEBUG)
#else
#define LOG_LEVEL_MASK (ALERT_LEVELS | LOG_LEVEL_MESSAGE | LOG_LEVEL_INFO)
#endif


static FILE *__stdout = 0;
static FILE *__stderr = 0;
static int __initialized = 0;

static FILE *
mklevel_prefix(char level_prefix[STRING_BUFFER_SIZE], LogLevelFlags log_level)
{
    FILE *dest = __stdout;

    switch (log_level) {
        case LOG_LEVEL_ERROR:
            strcpy(level_prefix, "ERROR");
            dest = __stderr;
            break;
        case LOG_LEVEL_CRITICAL:
            strcpy(level_prefix, "CRITICAL");
            dest = __stderr;
            break;
        case LOG_LEVEL_WARNING:
            strcpy(level_prefix, "WARNING");
            dest = __stderr;
            break;
        case LOG_LEVEL_MESSAGE:
            strcpy(level_prefix, "Message");
            dest = __stderr;
            break;
        case LOG_LEVEL_INFO:
            strcpy(level_prefix, "INFO");
            break;
        case LOG_LEVEL_DEBUG:
            strcpy(level_prefix, "DEBUG");
            break;
        default:
            strcpy(level_prefix, "LOG");
            break;
    }
    if (log_level & ALERT_LEVELS)
        strcat(level_prefix, " **");

    return dest;
}


#define LOG_LEN_MAX 2048
void
unihan_logv(const char *log_domain, LogLevelFlags log_level, const char *format, va_list args)
{
    log_level &= LOG_LEVEL_MASK;
    if (!log_level)
        return;

    char level_prefix[STRING_BUFFER_SIZE];
    FILE *fd = mklevel_prefix(level_prefix, log_level);

    char message[LOG_LEN_MAX];
    vsnprintf(message, LOG_LEN_MAX-1, format, args);

#if USE_SYSLOG
    syslog(LOG_INFO, "(%s:%lu): %s %s: %s",
            "unihan2", (unsigned long)getpid(),
            (log_domain)? log_domain : "(unknown)", level_prefix, 
            (message)? message : "(NULL) message");
#else
    fprintf(fd, "(%s:%lu): %s %s: %s\n",
            "unihan2", (unsigned long)getpid(),
            (log_domain)? log_domain : "(unknown)", level_prefix, 
            (message)? message : "(NULL) message");
#endif
}


void
unihan_log(const char *log_domain, LogLevelFlags log_level, const char *format, ...)
{
    va_list args;
    va_start(args, format);
    unihan_logv(log_domain, log_level, format, args);
    va_end(args);
}


void
unihan_log_set_stdout(FILE *stdout_fd)
{
    __stdout = stdout_fd;
}


void
unihan_log_set_stderr(FILE *stderr_fd)
{
    __stderr = stderr_fd;
}


void
unihan_log_init(void)
{
    if (!__initialized) {
        __stdout = stdout;
        __stderr = stderr;
        __initialized = 1;
    }
}


// vi:ts=4:sw=4:nowrap:cin:expandtab
